home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / video / fly8111-.000 / fly8111- / fly8 / loop.c < prev    next >
C/C++ Source or Header  |  1979-12-31  |  13KB  |  604 lines

  1. /* --------------------------------- loop.c --------------------------------- */
  2.  
  3. /* This is part of the flight simulator 'fly8'.
  4.  * Author: Eyal Lebedinsky (eyal@ise.canberra.edu.au).
  5. */
  6.  
  7. /* This is the main 'busy-loop' of the simulation.
  8. */
  9.  
  10. #include "plane.h"
  11.  
  12.  
  13. LOCAL_FUNC int    NEAR FASTCALL simulate_world (void);
  14. LOCAL_FUNC void    NEAR render_bg (OBJECT *pov, int type, int frame,
  15.             int hudinfront);
  16. LOCAL_FUNC void    NEAR render_fg (OBJECT *pov, int type, int frame,
  17.             int hudinfront);
  18. LOCAL_FUNC void    NEAR FASTCALL render_picture (void);
  19. LOCAL_FUNC void    NEAR FASTCALL show_picture (void);
  20.  
  21. extern void FAR
  22. active_loop (Ulong t)
  23. {
  24.     st.present += t;
  25.     st.ObjectTimeout = st.present + TO_OBJECT;
  26.     st.PlayerTimeout = st.present + TO_PLAYER;
  27.  
  28.     if (t > 1000L)            /* ignore long pauses */
  29.         st.interval = REFRESH;
  30.     else
  31.         st.interval = (int)t;
  32.  
  33.     st.dither = Frand () % 1000;
  34.  
  35.     Tm->Interval (TMR_START, 0L);
  36.  
  37.     if (!(st.flags & SF_PAUSED)) {
  38.         if (simulate_world ())
  39.             die ();
  40.  
  41.         render_picture ();    /* build picture into display list */
  42.     }
  43.  
  44.     show_picture ();        /* draw display list on screen */
  45.  
  46. /* Gather stats.
  47. */
  48.     st.misc[0] = (int)Tm->Interval (TMR_STOP, 10000L);
  49.     st.misc[2] = (int)STATS_TIME3D;
  50.     st.misc[3] = (int)STATS_TIMESIM;
  51.     st.misc[4] = (int)STATS_TIMESYNC;
  52.     st.misc[5] = (int)STATS_TIMEHDD;
  53.  
  54.     ++STATS_FRAMESCOUNT;
  55.     STATS_TIMETOTAL += st.misc[0];
  56.     STATS_TIMEVIDEO += st.misc[1];
  57.     STATS_TTIME3D += STATS_TIME3D;
  58.     STATS_TTIMESIM += STATS_TIMESIM;
  59.     STATS_TTIMESYNC += STATS_TIMESYNC;
  60.     STATS_TTIMEHDD += STATS_TIMEHDD;
  61.  
  62.     STATS_TIME3D = 0L;
  63.     STATS_TIMESIM = 0L;
  64.     STATS_TIMESYNC = 0L;
  65.     STATS_TIMEHDD = 0L;
  66. }
  67.  
  68. LOCAL_FUNC int NEAR FASTCALL
  69. simulate_world (void)
  70. /*
  71.  * Do the global housekeeping. This routine is called repeatedly from the
  72.  * main program just before the objects simulation.
  73. */
  74. {
  75.     if (st.quiet >= 2 && IS_PLANE (CC)) {        /* engine noise */
  76. #if 0
  77.         Snd->Effect (EFF_ENGINE, SND_PARMS, iabs (CC->speed/4));
  78.         Snd->Effect (EFF_ENGINE, SND_PARMS, iabs (EE(CC)->thrust/4));
  79. #endif
  80.         Snd->Effect (EFF_ENGINE, SND_PARMS, iabs (EE(CC)->power/16));
  81.     }
  82.  
  83.     if (objects_dynamics (st.interval))
  84.         return (1);
  85.  
  86.     if (land_update (CV))
  87.         return (1);
  88.  
  89.     return (0);
  90. }
  91.  
  92. /* initiate the screen drawing structures.
  93. */
  94. extern void FAR
  95. screen_start (void)
  96. {
  97.     if (st.flags1 & SF_DBUFFERING) {
  98.         Gr->SetVisual (st.which_buffer);
  99.         Gr->SetActive (1-st.which_buffer);
  100.     } else {
  101.         if (Gr->SetVisual)
  102.             Gr->SetVisual (0);
  103.         if (Gr->SetActive)
  104.             Gr->SetActive (0);
  105.     }
  106.     show_fixed (0);                /* show */
  107. }
  108.  
  109. /* empty all screen related structures, drain display lists.
  110. */
  111. extern void FAR
  112. screen_empty (void)
  113. {
  114.     if (st.flags1 & SF_DBUFFERING) {
  115.         Gr->SetActive (st.which_buffer);
  116.         if (Gr->Clear)
  117.             Gr->Clear (CS);
  118.         else {
  119.             buffers_erase (0);
  120.             buffers_erase (1);
  121.         }
  122.         Gr->SetActive (1-st.which_buffer);
  123.     }
  124.     if (Gr->Clear)
  125.         Gr->Clear (CS);
  126.     else {
  127.         buffers_erase (0);
  128.         buffers_erase (1);
  129.     }
  130.     buffers_free (0);
  131.     buffers_free (1);
  132.  
  133.     if (!Gr->Clear)
  134.         show_fixed (1);
  135. }
  136.  
  137. extern void FAR
  138. double_buffer (int mode)
  139. {
  140.     if (!((mode ^ st.flags1) & SF_DBUFFERING))
  141.         return;
  142.     if (CS->device->npages > 1) {
  143.         sim_set ();
  144.         screen_empty ();
  145.         st.flags1 ^= SF_DBUFFERING;
  146.         screen_start ();
  147.         sim_reset ();
  148.         MsgPrintf (50, "%s buffering",
  149.             st.flags1 & SF_DBUFFERING ? "double" : "single");
  150.     } else
  151.         MsgPrintf (50, "no double buffering");
  152. }
  153.  
  154. LOCAL_FUNC void NEAR
  155. draw_border (int orgx, int orgy, int sizex, int sizey, int bg, int bo)
  156. {
  157.     int    xl, xr, yt, yb;
  158.  
  159.  
  160.     xl = orgx - sizex;
  161.     xr = orgx + sizex;
  162.     yt = orgy - sizey;
  163.     yb = orgy + sizey;
  164.  
  165. /* draw the border
  166. */
  167.     if (!(st.flags & SF_BLANKER)) {
  168.         bo = st.colors[bo];
  169.         Gr->MoveTo (xl, yt);
  170.         Gr->DrawTo (xr, yt, bo);
  171.         Gr->DrawTo (xr, yb, bo);
  172.         Gr->DrawTo (xl, yb, bo);
  173.         Gr->DrawTo (xl, yt, bo);
  174.     }
  175.  
  176. /* fill in the background
  177. */
  178.     ++xl;
  179.     --xr;
  180.     bg = st.colors[bg];
  181.     while (++yt < yb) {
  182.         Gr->MoveTo (xl, yt);
  183.         Gr->DrawTo (xr, yt, bg);
  184.         sys_poll (9);
  185.     }
  186. }
  187.  
  188. LOCAL_FUNC void NEAR FASTCALL
  189. show_border (VIEW *v, int bg, int bo, int dx)
  190. {
  191.     int    orgx, orgy, sizex, sizey;
  192.  
  193.     orgx  = fmul (v->window->orgx, v->screen->sizex) + v->screen->minx;
  194.     orgy  = fmul (v->window->orgy, v->screen->sizey) + v->screen->miny;
  195.     sizex = fmul (v->window->maxx, v->screen->sizex);
  196.     sizey = fmul (v->window->maxy, v->screen->sizey);
  197.  
  198.     draw_border (orgx, orgy, sizex, sizey, bg, bo);
  199.     if (dx)
  200.         draw_border (orgx+dx, orgy, sizex, sizey, bg, bo);
  201. }
  202.  
  203. LOCAL_FUNC void NEAR FASTCALL
  204. show_borders (int del)
  205. {
  206.     int    dx, i;
  207.  
  208.     dx = (VIS_STEREOSCOPIC == st.stereo)
  209.         ? fmul (muldiv(CW->maxx, 2*st.gap+2, st.gap-1), CS->sizex)
  210.         : 0;
  211.  
  212.     for (i = 0; i < NHDD; ++i) {
  213.         if (st.hdd[i].view.window)
  214.             show_border (&st.hdd[i].view, st.hdd[i].BgColor,
  215.                 del ? st.hdd[i].BgColor : st.hdd[i].BoColor,
  216.                 0);
  217.     }
  218.     show_border (CVIEW, CS->BgColor, del ? CS->BgColor : CS->BoColor, dx);
  219. }
  220.  
  221. LOCAL_FUNC void NEAR FASTCALL
  222. show_fixed_page (int del)
  223. {
  224.     show_borders (del);
  225. }
  226.  
  227. extern void FAR
  228. show_fixed (int del)
  229. {
  230.     if (Gr->SetWriteMode)
  231.         Gr->SetWriteMode (T_MSET);
  232.  
  233.     if (st.flags1 & SF_DBUFFERING) {
  234.         Gr->SetActive (st.which_buffer);
  235.         show_fixed_page (del);
  236.         Gr->SetActive (1-st.which_buffer);
  237.     }
  238.     show_fixed_page (del);
  239. }
  240.  
  241. LOCAL_FUNC void NEAR
  242. render_bg (OBJECT *pov, int type, int frame, int hudinfront)
  243. {
  244.     Tm->Interval (TMR_START, 0L);
  245.     show_sky (CVIEW, pov);
  246.  
  247.     if (frame && !hudinfront)
  248.         show_main (CVIEW, pov, type, 1);
  249.     STATS_TIMEHDD += Tm->Interval (TMR_STOP, 10000L);
  250. }
  251.  
  252. LOCAL_FUNC void NEAR
  253. render_fg (OBJECT *pov, int type, int frame, int hudinfront)
  254. {
  255.     Tm->Interval (TMR_START, 0L);
  256.     show_main (CVIEW, pov, type, (frame && !hudinfront) ? 0 : 1);
  257.     show_inst (CVIEW, CV);
  258.     STATS_TIMEHDD += Tm->Interval (TMR_STOP, 10000L);
  259. }
  260.  
  261. /* st.which_buffer indicated which buffer is now visible.
  262.  * bufold is the currently active (invisible) page
  263.  *    it is drawn,  then becomes visible (inactive)
  264.  * bufnew is the cuurently visible (inactive) page
  265.  *    it is erased, then becomes active (invisible)
  266. */
  267.  
  268. LOCAL_FUNC void NEAR FASTCALL
  269. show_picture (void)
  270. {
  271.     int    bufold, bufnew;
  272.  
  273.     Tm->Interval (TMR_START, 0L);
  274.  
  275.     if (st.flags & SF_CLEARED) {
  276.         st.flags &= ~SF_CLEARED;
  277.         show_fixed (0);
  278.     }
  279.  
  280.     if ((st.flags & SF_PAUSED) && (VIS_ALTERNATING != st.stereo))
  281.         goto ret;
  282.  
  283.     bufnew = st.which_buffer;
  284.     st.which_buffer = (st.which_buffer+1)%NBUFS;
  285.     bufold = st.which_buffer;
  286.  
  287.     if (st.flags1 & SF_DBUFFERING) {
  288.         Gr->SetActive (bufold);            /* access new page */
  289.         buffers_show (bufold);            /* draw new page */
  290.         if (Gr->Clear)
  291.             show_fixed_page (0);
  292.         Tm->Interval (TMR_START, 0L);
  293.         Gr->SetVisual (bufold);            /* show new page */
  294.         if (VIS_ALTERNATING == st.stereo)
  295.             Gr->Shutters (bufold);
  296.         STATS_TIMESYNC = Tm->Interval (TMR_STOP, 10000L);
  297.  
  298.         Gr->SetActive (bufnew);            /* access old page */
  299.         buffers_erase (bufnew);            /* erase old page */
  300.         buffers_free (bufnew);
  301.     } else {
  302.         buffers_erase (bufnew);            /* erase old page */
  303.         buffers_free (bufnew);
  304.         if (VIS_ALTERNATING == st.stereo)
  305.             Gr->Shutters (bufold);
  306.         buffers_show (bufold);            /* show new page */
  307.         if (Gr->Clear)
  308.             show_fixed_page (0);
  309.         Tm->Interval (TMR_START, 0L);
  310.         if (Gr->SetVisual)
  311.             Gr->SetVisual (0);        /* show page */
  312.         STATS_TIMESYNC = Tm->Interval (TMR_STOP, 10000L);
  313.     }
  314. ret:
  315.     if (Gr->Flush) {
  316.         Tm->Interval (TMR_START, 0L);
  317.         Gr->Flush ();
  318.         STATS_TIMESYNC = Tm->Interval (TMR_STOP, 10000L);
  319.     }
  320.     st.misc[1] = (int)(Tm->Interval (TMR_STOP, 10000L) - STATS_TIMESYNC);
  321. }
  322.  
  323. extern OBJECT * FAR
  324. get_viewer (int type)
  325. {
  326.     OBJECT    *pov;
  327.  
  328.     for (pov = CO; pov; pov = pov->next) {
  329.         if (pov->name == O_VIEWER && pov->misc[0] == type)
  330.             break;
  331.     }
  332.     return (pov);
  333. }
  334.  
  335. extern void FAR
  336. save_viewport (OBJECT *p)
  337. {
  338.     if (!p->viewport) {
  339.         if (!NEW (p->viewport))
  340.             return;
  341.     }
  342.     memcpy (p->viewport, CP, sizeof (*p->viewport));
  343. }
  344.  
  345. extern void FAR
  346. get_viewport (OBJECT *p)
  347. {
  348.     if (p->viewport)
  349.         memcpy (CP, p->viewport, sizeof (*CP));
  350.     else {
  351.         CP->flags = 0;
  352.         CP->x     = 0*FONE;        /* viewer at center */
  353.         CP->y     = 0*FONE;
  354.         CP->shift = 0;
  355.         CP->eyex  = 0;
  356.         CP->eyey  = 0;
  357.         CP->eyez  = 0;
  358.         CP->rotx  = 0;
  359.         CP->roty  = 0;
  360.         CP->rotz  = 0;
  361.     }
  362. }
  363.  
  364. /* Render the whole screen. Some data may already be in the display list
  365.  * from spurious debug stuff.
  366. */
  367.  
  368. LOCAL_FUNC void NEAR FASTCALL
  369. render_picture (void)
  370. {
  371.     ANGLE    cross;                /* stereo cross-eyed angle */
  372.     int    rev, shift, rotz, hud, scene, hudinfront;
  373.     int    sscopic_shift;
  374.     int    frame;                /* 0=mono 1=left 2=right */
  375.     int    type;                /* 0=main other=HDD type */
  376.     OBJECT    *pov;
  377.     Ushort    save_colors[NCOLORS];
  378.     int    i;
  379.     Ushort    color;
  380.  
  381.     st.flags |= SF_MAIN;            /* main display */
  382.  
  383.     if (st.flags1 & SF_EXTVIEW) {        /* find viewer */
  384.         type = st.extview;
  385.         hud = (HDT_HUD == type);
  386.         scene = scenery (type);
  387.         if (scene || hud) {
  388.             pov = get_viewer (hud ? HDT_FRONT : type);
  389.             if (!pov) {
  390.                 pov = CV;
  391.                 type = 0;
  392.             }
  393.         } else
  394.             pov = CV;
  395.     } else {
  396.         pov = CV;
  397.         type = 0;
  398.         scene = 1;
  399.     }
  400.  
  401.     cross = 0;    /*ASIN (fdiv (st.paralax, st.focus));*/
  402.  
  403.     if (st.stereo) {
  404.         rev = st.flags1 & SF_STEREOREV;
  405.         if (!scene)
  406.             hudinfront = 1;
  407.         else
  408.             hudinfront = st.flags1 & SF_HUDINFRONT;
  409.         if (VIS_ALTERNATING == st.stereo && st.which_buffer)
  410.             rev = !rev;
  411.         if (rev) {
  412.             shift = -st.paralax;    /* transverse: right eye */
  413.             rotz  = -cross;
  414.         } else {
  415.             shift = st.paralax;    /* parallel:   left eye */
  416.             rotz  = cross;
  417.         }
  418.         CP->shift -= shift;        /* left eye */
  419.         CP->rotz  += rotz;
  420.     } else {
  421.         shift = rotz = 0;        /* avoid compiler warning */
  422.         hudinfront = 0;
  423.     }
  424.  
  425.     if (VIS_REDBLUE == st.stereo) {
  426.         memcpy (save_colors, st.colors, sizeof (st.colors));
  427.         gr_mode (T_MOR);
  428.     } else
  429.         gr_mode (T_MSET);
  430.  
  431. /* First we show the left eye view. This is also used to show the single view
  432.  * (mono or alternating stereo).
  433. */
  434.     frame = VIS_REDBLUE == st.stereo ? 1 : 0;    /* mono/left frame */
  435.     if (frame) {
  436.         color = save_colors[ST_SLEFT];
  437.         for (i = 0; i < rangeof (st.colors); ++i)
  438.             st.colors[i] = color;
  439.     }
  440.  
  441.     if (scene) {
  442.         render_bg (pov, type, frame, hudinfront);
  443.         objects_show (0, CVIEW, pov, frame, 0, 0);
  444.     }
  445.  
  446.     if (st.stereo && hudinfront) {
  447.         CP->shift += shift;            /* back to center */
  448.         CP->rotz  -= rotz;
  449.     }
  450.  
  451.     if (VIS_REDBLUE != st.stereo)
  452.         render_fg (pov, type, frame, hudinfront);
  453.  
  454.     if (st.stereo && !hudinfront) {
  455.         CP->shift += shift;            /* back to center */
  456.         CP->rotz  -= rotz;
  457.     }
  458.         
  459. /* Second we show the right eye view (for non-alternating stereo).
  460. */
  461.     if (st.stereo && VIS_ALTERNATING != st.stereo) {
  462.         if (VIS_STEREOSCOPIC == st.stereo) {
  463.             sscopic_shift = muldiv (CW->maxx, 2*st.gap+2, st.gap-1);
  464.             CW->orgx += sscopic_shift;
  465.         }
  466.  
  467.         CP->shift += shift;            /* right eye */
  468.         CP->rotz  -= rotz;
  469.  
  470.         frame = VIS_REDBLUE == st.stereo ? 2 : 0; /* right frame */
  471.         if (frame) {
  472.             color = save_colors[ST_SRIGHT];
  473.             for (i = 0; i < rangeof (st.colors); ++i)
  474.                 st.colors[i] = color;
  475.         }
  476.         if (scene) {
  477.             render_bg (pov, type, frame, hudinfront);
  478.             objects_show (0, CVIEW, pov, frame, 0, 0);
  479.         }
  480.  
  481.         if (hudinfront) {
  482.             CP->shift -= shift;        /* back to center */
  483.             CP->rotz  += rotz;
  484.             if (VIS_REDBLUE == st.stereo) {
  485.                 color = save_colors[ST_SBOTH];
  486.                 for (i = 0; i < rangeof (st.colors); ++i)
  487.                     st.colors[i] = color;
  488.             }
  489.         }
  490.  
  491.         render_fg (pov, type, frame, hudinfront);
  492.  
  493.         if (!hudinfront) {
  494.             CP->shift -= shift;        /* back to center */
  495.             CP->rotz  += rotz;
  496.         }
  497.  
  498.         if (VIS_STEREOSCOPIC == st.stereo)
  499.             CW->orgx -= sscopic_shift;
  500.     }
  501.  
  502.     buffer_close ();
  503.     st.bufs[1-st.which_buffer] = st.buf[HEAD];
  504.     st.buf[HEAD] = st.buf[TAIL] = 0;
  505.  
  506.     st.flags &= ~SF_MAIN;                /* secondary displays */
  507.  
  508.     if (VIS_REDBLUE == st.stereo) {
  509.         color = save_colors[ST_SBOTH];
  510.         for (i = 0; i < rangeof (st.colors); ++i)
  511.             st.colors[i] = color;
  512.     }
  513.  
  514.     show_hdd ();
  515.  
  516.     if (VIS_REDBLUE == st.stereo)
  517.         memcpy (st.colors, save_colors, sizeof (st.colors));
  518.  
  519.     STATS_DISPLAYLISTSIZE = buffers_size (1-st.which_buffer);
  520. }
  521.  
  522. static BUFFER     *pause_buf = NULL;
  523.  
  524. extern void FAR
  525. pause_set (Ushort mode)
  526. {
  527.     int    orgx, orgy, sizex, sizey;
  528.     BUFFER     *save_buf[2] = {NULL, NULL};
  529.     short    save_avail;
  530.  
  531.     if (!((mode ^ st.flags) & SF_PAUSED))
  532.         return;
  533.  
  534.     if ((mode & SF_PAUSED) && (st.network & NET_ON)) {
  535.         MsgEPrintf (30, "cannot pause on net");
  536.         return;
  537.     }
  538.  
  539.     if (!(st.flags & SF_PAUSEMSG)) {
  540.         st.flags = (st.flags & ~SF_PAUSED) | mode;
  541.         return;
  542.     }
  543.  
  544.     sim_set ();        /* we want immediate response */
  545.  
  546. /* Get 2D display area parameters.
  547. */
  548.     get_area (CVIEW, &orgx, &orgy, &sizex, &sizey);
  549.  
  550.     if (mode & SF_PAUSED) {
  551.  
  552. /* save current buf
  553. */
  554.         save_buf[HEAD] = st.buf[HEAD];
  555.         save_buf[TAIL] = st.buf[TAIL];
  556.         save_avail     = st.buf_avail;
  557.         buffer_close ();
  558.         st.buf[HEAD] = st.buf[TAIL] = 0;
  559.  
  560. /* create the 'Paused' buf
  561. */
  562.         gr_mode (T_MXOR);
  563.         stroke_str (orgx - sizex + 2, orgy - sizey + 2 + st.StFontSize,
  564.             "Paused", st.StFontSize, ST_INFO);
  565.  
  566. /* save it
  567. */
  568.         buffer_close ();
  569.         pause_buf = st.buf[HEAD];
  570.  
  571. /* restore original buf
  572. */
  573.         st.buf[HEAD] = save_buf[HEAD];
  574.         st.buf[TAIL] = save_buf[TAIL];
  575.         st.buf_p     = st.buf[TAIL] ? st.buf[TAIL]->p : NULL;
  576.         st.buf_avail = save_avail;
  577.  
  578. /* show the 'Paused' buf
  579. */
  580.         if (st.flags1 & SF_DBUFFERING) {
  581.             Gr->SetActive (st.which_buffer);
  582.             buffer_show (pause_buf);
  583.             Gr->SetActive (1-st.which_buffer);
  584.         }
  585.         buffer_show (pause_buf);
  586.  
  587.         st.flags |= SF_PAUSED;
  588.     } else {
  589.         st.flags &= ~SF_PAUSED;
  590.  
  591. /* erase the 'Paused' buf, then free it
  592. */
  593.         if (st.flags1 & SF_DBUFFERING) {
  594.             Gr->SetActive (st.which_buffer);
  595.             buffer_show (pause_buf);
  596.             Gr->SetActive (1-st.which_buffer);
  597.         }
  598.         buffer_show (pause_buf);
  599.         buffer_free (pause_buf);
  600.     }
  601.  
  602.     sim_reset ();
  603. }
  604.